﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using wwl.Domain.Entities.Rbac;

namespace wwl.DataAccess.Mappings.Rbac
{
  /// <summary>
  /// 权限实体映射配置类（EF Core 数据映射）
  /// 负责配置权限领域实体与数据库表 rbac_permission 之间的映射关系和层级约束
  /// 核心价值：实现权限数据的规范化存储和层级管理，支撑细粒度的系统访问控制
  /// 设计目标：构建灵活的权限树形结构，支持菜单导航、操作控制和按钮权限的完整权限体系
  /// </summary>
  public class PermissionMap : IEntityTypeConfiguration<Permission>
  {
    /// <summary>
    /// 配置权限实体的数据库映射细节
    /// </summary>
    /// <param name="builder">实体类型构建器，提供流畅API配置权限实体的映射规则</param>
    /// <remarks>
    /// 1. 层级关系：通过自引用外键实现权限的树形结构，支持无限层级的权限菜单设计
    /// 2. 资源绑定：资源路径字段实现权限与系统资源的精确映射，支撑自动化的权限校验机制
    /// 3. 类型分类：权限类型字段区分菜单、操作、按钮等不同粒度的权限控制需求
    /// 4. 多租户隔离：完善的租户支持确保各租户权限体系的独立性和定制化能力
    /// </remarks>
    public void Configure(EntityTypeBuilder<Permission> builder)
    {
      // 指定表名：明确映射到 rbac_permission 表，保持RBAC模块权限表命名的一致性
      builder.ToTable("rbac_permission");

      // 配置主键：使用字符串类型主键，支持灵活的权限标识生成策略
      builder.HasKey(x => x.Id);

      #region 属性映射配置
      // 主键映射：64字符长度与其他实体主键保持一致，NOT NULL 约束确保权限标识完整性
      builder.Property(x => x.Id)
          .HasColumnName("id")
          .HasMaxLength(64)
          .IsRequired();

      // 权限编码映射：唯一索引保障权限编码全局唯一，权限校验和技术控制的核心标识字段
      builder.Property(x => x.PermCode)
          .HasColumnName("perm_code")
          .HasMaxLength(64)
          .IsRequired();

      // 权限名称映射：128字符长度支持详细的权限描述，权限配置界面的展示核心字段
      builder.Property(x => x.PermName)
          .HasColumnName("perm_name")
          .HasMaxLength(128)
          .IsRequired();

      // 权限类型映射：字符串存储提升可读性，检查约束确保权限类型值的业务合法性
      builder.Property(x => x.PermType)
          .HasColumnName("perm_type")
          .HasConversion<string>()
          .HasMaxLength(20)
          .IsRequired();

      // 父权限标识映射：自引用外键实现权限层级，可空设计标识根级权限节点
      builder.Property(x => x.ParentId)
          .HasColumnName("parent_id")
          .HasMaxLength(64);

      // 资源路径映射：255字符长度支持复杂的URL模式和API路径，权限自动匹配的技术基础
      builder.Property(x => x.ResourcePath)
          .HasColumnName("resource_path")
          .HasMaxLength(255);

      // 租户标识映射：支持多租户权限体系隔离，可空设计适应系统级基础权限场景
      builder.Property(x => x.TenantId)
          .HasColumnName("tenant_id")
          .HasMaxLength(64);

      // 基础实体属性映射：继承自 BaseEntity 的审计字段和软删除支持
      builder.Property(x => x.CreatedTime)
          .HasColumnName("created_time")
          .IsRequired();

      builder.Property(x => x.UpdatedTime)
          .HasColumnName("updated_time")
          .IsRequired();

      builder.Property(x => x.CreatedBy)
          .HasColumnName("created_by")
          .HasMaxLength(64)
          .IsRequired();

      builder.Property(x => x.Remarks)
          .HasColumnName("remarks")
          .HasColumnType("text");

      builder.Property(x => x.IsDeleted)
          .HasColumnName("is_deleted")
          .HasDefaultValue(false);
      #endregion

      #region 外键关系配置
      // 自引用关系：建立权限与父权限的多对一关系，SET NULL删除策略保留子权限的独立性
      builder.HasOne(p => p.Parent)
          .WithMany(p => p.Children)
          .HasForeignKey(p => p.ParentId)
          .OnDelete(DeleteBehavior.SetNull);
      #endregion

      #region 索引配置
      // 权限编码唯一索引：保障权限标识的唯一性，提升权限编码查询和校验性能
      builder.HasIndex(x => x.PermCode)
          .IsUnique()
          .HasDatabaseName("ix_rbac_permission_perm_code");

      // 父权限ID索引：支持通过父权限查询所有子权限，优化权限树构建和层级遍历性能
      builder.HasIndex(x => x.ParentId)
          .HasDatabaseName("ix_rbac_permission_parent_id");

      // 资源路径索引：支持通过资源路径快速匹配所需权限，优化自动权限校验场景性能
      builder.HasIndex(x => x.ResourcePath)
          .HasDatabaseName("ix_rbac_permission_resource_path");

      // 租户索引：支持按租户查询权限列表，优化多租户权限体系隔离场景的查询性能
      builder.HasIndex(x => x.TenantId)
          .HasDatabaseName("ix_rbac_permission_tenant_id");
      #endregion

      #region 约束配置
      // 权限类型检查约束：数据库层面保障权限类型值的业务合法性
      builder.ToTable(tableBuilder =>
      {
        tableBuilder.HasCheckConstraint(
            "ck_rbac_permission_type",
            "perm_type IN ('MENU', 'OPERATION', 'BUTTON')"
        );
      });
      #endregion
    }
  }
}